package com.xxl.job.admin.core.conf;

import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.xxl.job.admin.core.alarm.JobAlarmer;
import com.xxl.job.admin.core.model.XxlJobTenant;
import com.xxl.job.admin.core.scheduler.XxlJobScheduler;
import com.xxl.job.admin.dao.*;
import jakarta.annotation.Resource;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;

import javax.sql.DataSource;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.Arrays;

/**
 * xxl-job config
 *
 * @author xuxueli 2017-04-28
 */

@Component
public class XxlJobAdminConfig implements InitializingBean, DisposableBean {

    private static XxlJobAdminConfig adminConfig = null;
    public static XxlJobAdminConfig getAdminConfig() {
        return adminConfig;
    }


    // ---------------------- XxlJobScheduler ----------------------

    private XxlJobScheduler xxlJobScheduler;

    @Override
    public void afterPropertiesSet() throws Exception {
        adminConfig = this;

        xxlJobScheduler = new XxlJobScheduler();
        xxlJobScheduler.init();
    }

    @Override
    public void destroy() throws Exception {
        xxlJobScheduler.destroy();
    }


    // ---------------------- XxlJobScheduler ----------------------

    // conf
    @Value("${xxl.job.i18n}")
    private String i18n;

    @Value("${xxl.job.accessToken}")
    private String accessToken;

    @Value("${xxl.job.tenant.switch.open}")
    private boolean tenantSwitchOpen;

    @Value("${xxl.job.timeout}")
    private int timeout;

    @Value("${spring.mail.from}")
    private String emailFrom;

    @Value("${xxl.job.triggerpool.fast.max}")
    private int triggerPoolFastMax;

    @Value("${xxl.job.triggerpool.slow.max}")
    private int triggerPoolSlowMax;

    @Value("${xxl.job.logretentiondays}")
    private int logretentiondays;

    @Value("${xxl.job.executor.log-to-db}")
    private boolean logToDb;

    @Value("${xxl.job.admin.machine.refresh.time}")
    private long machineRefreshTime;
    @Value("${xxl.job.admin.machine.death.time}")
    private long machineDeathTime;

    @Value("${server.port}")
    private String serverPort;

    // dao, service

    @Resource
    private XxlJobLogDao xxlJobLogDao;
    @Resource
    private XxlJobInfoDao xxlJobInfoDao;
    @Resource
    private XxlJobRegistryDao xxlJobRegistryDao;
    @Resource
    private XxlJobGroupDao xxlJobGroupDao;
    @Resource
    private XxlJobLogReportDao xxlJobLogReportDao;
    @Resource
    private JavaMailSender mailSender;
    @Resource
    private DataSource dataSource;
    @Resource
    private JobAlarmer jobAlarmer;

    @Resource
    private XxlJobTenantDao xxlJobTenantDao;

    @Resource
    private XxlJobLogDetailDao xxlJobLogDetailDao;

    @Resource
    private XxlJobAdminMachineDao xxlJobAdminMachineDao;

    @Resource
    private XxlJobAlarmConfigDao xxlJobAlarmConfigDao;

    @Resource
    private XxlJobAlarmRecordDao xxlJobAlarmRecordDao;


    public String getMachineAddress() throws UnknownHostException {
        return InetAddress.getLocalHost().getHostAddress()+":"+serverPort;
    }

    public String getI18n() {
        if (!Arrays.asList("zh_CN", "zh_TC", "en").contains(i18n)) {
            return "zh_CN";
        }
        return i18n;
    }

    public String getAccessToken() {
        return accessToken;
    }

    public boolean isTenantSwitchOpen() {
        return tenantSwitchOpen;
    }


    public String getAccessToken(String tenantId) {
        //非多租户模式
        if(!tenantSwitchOpen){
            return accessToken;
        }
        if(!StringUtils.hasLength(tenantId)){
           throw new RuntimeException("tenant id can not be null");
        }
        XxlJobTenant tenant = xxlJobTenantDao.selectOne(Wrappers.lambdaQuery(XxlJobTenant.class).eq(XxlJobTenant::getTenantId, tenantId));
        if (tenant != null) {
            return tenant.getTenantId() + ":" + tenant.getAccessToken();
        }
        return null;
    }

    public int getTimeout() {
        return timeout;
    }

    public String getEmailFrom() {
        return emailFrom;
    }

    public int getTriggerPoolFastMax() {
        if (triggerPoolFastMax < 200) {
            return 200;
        }
        return triggerPoolFastMax;
    }

    public int getTriggerPoolSlowMax() {
        if (triggerPoolSlowMax < 100) {
            return 100;
        }
        return triggerPoolSlowMax;
    }

    public int getLogretentiondays() {
        if (logretentiondays < 3) {
            return -1;  // Limit greater than or equal to 3, otherwise close
        }
        return logretentiondays;
    }

    public XxlJobLogDao getXxlJobLogDao() {
        return xxlJobLogDao;
    }

    public XxlJobInfoDao getXxlJobInfoDao() {
        return xxlJobInfoDao;
    }

    public XxlJobRegistryDao getXxlJobRegistryDao() {
        return xxlJobRegistryDao;
    }

    public XxlJobGroupDao getXxlJobGroupDao() {
        return xxlJobGroupDao;
    }

    public XxlJobLogReportDao getXxlJobLogReportDao() {
        return xxlJobLogReportDao;
    }

    public JavaMailSender getMailSender() {
        return mailSender;
    }

    public DataSource getDataSource() {
        return dataSource;
    }

    public JobAlarmer getJobAlarmer() {
        return jobAlarmer;
    }

    public XxlJobTenantDao getXxlJobTenantDao() {
        return xxlJobTenantDao;
    }

    public XxlJobLogDetailDao getXxlJobLogDetailDao() {
        return xxlJobLogDetailDao;
    }

    public void setXxlJobLogDetailDao(XxlJobLogDetailDao xxlJobLogDetailDao) {
        this.xxlJobLogDetailDao = xxlJobLogDetailDao;
    }

    public boolean isLogToDb() {
        return logToDb;
    }

    public void setLogToDb(boolean logToDb) {
        this.logToDb = logToDb;
    }

    public XxlJobAdminMachineDao getXxlJobAdminMachineDao() {
        return xxlJobAdminMachineDao;
    }

    public void setXxlJobAdminMachineDao(XxlJobAdminMachineDao xxlJobAdminMachineDao) {
        this.xxlJobAdminMachineDao = xxlJobAdminMachineDao;
    }

    public long getMachineDeathTime() {
        return machineDeathTime;
    }

    public void setMachineDeathTime(long machineDeathTime) {
        this.machineDeathTime = machineDeathTime;
    }

    public long getMachineRefreshTime() {
        return machineRefreshTime;
    }

    public void setMachineRefreshTime(long machineRefreshTime) {
        this.machineRefreshTime = machineRefreshTime;
    }

    public XxlJobAlarmConfigDao getXxlJobAlarmConfigDao() {
        return xxlJobAlarmConfigDao;
    }

    public void setXxlJobAlarmConfigDao(XxlJobAlarmConfigDao xxlJobAlarmConfigDao) {
        this.xxlJobAlarmConfigDao = xxlJobAlarmConfigDao;
    }

    public XxlJobAlarmRecordDao getXxlJobAlarmRecordDao() {
        return xxlJobAlarmRecordDao;
    }

    public void setXxlJobAlarmRecordDao(XxlJobAlarmRecordDao xxlJobAlarmRecordDao) {
        this.xxlJobAlarmRecordDao = xxlJobAlarmRecordDao;
    }
}
